#!/usr/bin/env python

import string
import os.path

from utils import tracer
from gui.mdiFrame import MDIFrame
from xml.dom.minidom import parse, parseString

class PluginInfo:
  _name = ''
  _version = ''
  _author = ''
  _description = ''
  _moduleName = ''
  _module = None
  
  def __init__(self, name, version, author, description, moduleName):
    self._name = name
    self._version = version
    self._author = author
    self._description = description
    self._moduleName = moduleName

  def getName(self):
    return self._name

  def getVersion(self):
    return self._version

  def getAuthor(self):
    return self._author

  def getDescription(self):
    return self._description

  def getModuleName(self):
    return self._moduleName

  def setModule(self, module):
    self._module = module

  def getModule(self):
    return self._module

class PluginManager:
  
  def __init__(self):
    self._plugins = {}
    self._owner = None

    configPath = os.path.normpath(os.path.dirname(__file__))
    self._configFile = configPath + os.path.sep + 'plugins.xml'

  def setOwner(self, owner):
    if not owner is None:
      assert type(owner) is MDIFrame
      self._owner = owner
      self.loadConfig(self._configFile)
    else:
      self._owner = None

  def getPlugins(self):
    return self._plugins.values()

  def getPluginByName(self, name):
    if self._plugins.has_key(name):
      return self._plugins[name]
    return None

  def loadConfig(self, configFile):
    assert os.path.exists(configFile)
    
    dom = parse(configFile)
    self.createPluginDict(dom)
    self.loadModules()

  def createPluginDict(self, dom):
    pluginNodes = dom.getElementsByTagName("plugin")      
    for pluginNode in pluginNodes:
      if pluginNode.nodeType != pluginNode.ELEMENT_NODE:
        continue
      if not pluginNode.hasAttribute("name"):
        continue

      pluginName = pluginNode.getAttribute("name")

      pluginVer = ''
      if pluginNode.hasAttribute("version"):
        pluginVer = pluginNode.getAttribute("version")

      pluginAut = ''
      if pluginNode.hasAttribute("author"):
        pluginAui = pluginNode.getAttribute("author")

      pluginDesc = ''
      if pluginNode.hasAttribute("description"):
        pluginDesc = pluginNode.getAttribute("description")
      
      moduleNode = pluginNode.getElementsByTagName("module")[0]
      if moduleNode.nodeType != moduleNode.ELEMENT_NODE:
        continue
      if not moduleNode.hasAttribute("name"):
        continue
        
      moduleName = moduleNode.getAttribute("name").encode('ascii')

      self._plugins[pluginName] = PluginInfo(pluginName, pluginVer, pluginAut, pluginDesc, moduleName)
      
  def loadModules(self):
    tracer.writeln('-- Loading modules -----------------------------')
    
    for plugin in self._plugins.values():
      if plugin is None:
        continue
      
      tracer.writeln('  - %s' % plugin.getModuleName())

      mod = self.importModule(plugin.getModuleName())
      if mod != None:
        instance = mod.getInstance()
        plugin.setModule(instance)
        tracer.writeln('    Module Loaded. %s' % os.linesep)
      else:
        tracer.writeln('    Cannot load module! %s' % os.linesep)

  def importModule(self, name):
    try:
      mod = __import__(name)
      components = name.split('.')
      for comp in components[1:]:
        mod = getattr(mod, comp)
      return mod
    except Exception, err:
      tracer.writeln('    %s' % err)
      return None
    


###################################################################
# test codes
import wx

class TestApp(wx.App):
  def __init__(self):
    wx.App.__init__(self)
    
    frame = wx.Frame(None)

    mgr = PluginManager()
    mod = mgr.importModule('documentManager.documentManager')
    print dir(mod)
    pane = mod.getPane(frame)
    
    frame.Show(True)
    
    self.SetTopWindow(frame)

  def start(self):
    self.MainLoop()
    
if __name__ == '__main__':
  app = TestApp()
  app.start()

  
